package br.com.massai.model.entity;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

import br.com.massai.model.entity.pojo.Employee;
import br.com.massai.model.exceptions.ErrorCore;
import br.com.massai.model.exceptions.SystemException;
import br.com.massai.view.enums.Regime;

@Entity
@Table(name = "ENTRY")
@NamedQueries({
	@NamedQuery(name = "Entry.find", query = "SELECT e FROM Entry e"),
	@NamedQuery(name = "Entry.duplicate", query = "SELECT COUNT(e) FROM Entry e WHERE e.spreadsheet =:spreadsheet AND e.employee.epgCodigo =:epgCodigo")
})
public class Entry extends GenericEntity implements Comparable<Entry>, Cloneable {

	private static final long serialVersionUID = 6851623934095869094L;

	@Id
	@SequenceGenerator(name = "seqEntry", sequenceName = "seq_entry", allocationSize = 1)
	@GeneratedValue(generator = "seqEntry", strategy = GenerationType.SEQUENCE)
	private Long id;

	@Enumerated(EnumType.STRING)
	@Column(name = "REGIME", columnDefinition = "CHAR(1)")
	private Regime regime;

	@Column(name = "TOTAL_AMOUNT", precision = 10, scale = 2, columnDefinition = "NUMERIC(10,2)")
	private BigDecimal totalAmount;

	@Column(name = "TOTAL_PERCENTAGE", precision = 7, scale = 4, columnDefinition = "NUMERIC(7,4)")
	private BigDecimal totalPercentage;

	@Column(name = "VALUE_GRATIFICATION", precision = 10, scale = 2, columnDefinition = "NUMERIC(10,2)")
	private BigDecimal valueGratification;

	@ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.REFRESH)
	@JoinColumn(name = "SPREADSHEET_ID", referencedColumnName = "ID")
	private Spreadsheet spreadsheet;

	@Embedded
	private Employee employee;

	@OneToMany(fetch=FetchType.LAZY, mappedBy = "entry", cascade = CascadeType.ALL)
	@Fetch(FetchMode.JOIN)
	private List<EntryItem> entryItems;

	//PROPRIEDADES DA IMPORTACAO - FORTES
	@Column(name = "SALARIO_LIQUIDO", precision = 10, scale = 2, columnDefinition = "NUMERIC(10,2)")
	private BigDecimal salarioLiquido;

	@Column(name = "TOTAL_DESCONTOS", precision = 10, scale = 2, columnDefinition = "NUMERIC(10,2)")
	private BigDecimal totalDescontos;

	@Column(name = "TOTAL_PROVENTOS", precision = 10, scale = 2, columnDefinition = "NUMERIC(10,2)")
	private BigDecimal totalProventos;
	
	@Column(name = "HROAS_TRABALHADAS", precision = 10, scale = 2, columnDefinition = "NUMERIC(10,2)")
	private BigDecimal horasTrabalhadas;

	public Entry() {
		this.totalAmount = BigDecimal.ZERO.setScale(SCALE_VALUE);
		this.totalPercentage  = BigDecimal.ZERO.setScale(SCALE_PERCENTAGE);
		this.valueGratification = BigDecimal.ZERO.setScale(SCALE_VALUE);
		this.spreadsheet = new Spreadsheet();
		this.employee = new Employee();

		this.totalDescontos = BigDecimal.ZERO;
		this.totalProventos = BigDecimal.ZERO;
		this.salarioLiquido = BigDecimal.ZERO;
		this.horasTrabalhadas = BigDecimal.ZERO;

		this.entryItems = new ArrayList<>();
	}
	
	@Override
	public boolean equals(Object obj) {
		if(obj == null) return false;
		if(obj instanceof Entry)
			if(((Entry)obj).getId().equals(this.getId())) return true;

		return false;
	}

	@Override
	public int compareTo(Entry o) {
		if(this.employee != null && this.employee.getEpgCodigo() != null && this.employee.getEmpCodigo() != null) {
			int orderCargo = this.employee.getCargo().compareTo(o.getEmployee().getCargo());
			return (orderCargo != 0 ? orderCargo : this.employee.getNome().compareTo(o.getEmployee().getNome()));
		}
		return 0;
	}
	
	public Entry getClone() {
		try {
			return (Entry) super.clone();

		} catch (CloneNotSupportedException e) {
			throw new SystemException(ErrorCore.ERROR_CLONEABLE);
		}
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Regime getRegime() {
		return regime;
	}

	public void setRegime(Regime regime) {
		this.regime = regime;
	}

	public BigDecimal getTotalAmount() {
		return totalAmount;
	}

	public void setTotalAmount(BigDecimal totalAmount) {
		this.totalAmount = totalAmount;
	}

	public BigDecimal getTotalPercentage() {
		return totalPercentage;
	}

	public void setTotalPercentage(BigDecimal totalPercentage) {
		this.totalPercentage = totalPercentage;
	}

	public BigDecimal getValueGratification() {
		return valueGratification;
	}

	public void setValueGratification(BigDecimal valueGratification) {
		this.valueGratification = valueGratification;
	}

	public Spreadsheet getSpreadsheet() {
		return spreadsheet;
	}

	public void setSpreadsheet(Spreadsheet spreadsheet) {
		this.spreadsheet = spreadsheet;
	}

	public Employee getEmployee() {
		return employee;
	}

	public void setEmployee(Employee employee) {
		this.employee = employee;
	}

	public List<EntryItem> getEntryItems() {
		return entryItems;
	}

	public void setEntryItems(List<EntryItem> entryItems) {
		this.entryItems = entryItems;
	}

	public BigDecimal getSalarioLiquido() {
		return salarioLiquido;
	}

	public void setSalarioLiquido(BigDecimal salarioLiquido) {
		this.salarioLiquido = salarioLiquido;
	}

	public BigDecimal getTotalDescontos() {
		return totalDescontos;
	}

	public void setTotalDescontos(BigDecimal totalDescontos) {
		this.totalDescontos = totalDescontos;
	}

	public BigDecimal getTotalProventos() {
		return totalProventos;
	}

	public void setTotalProventos(BigDecimal totalProventos) {
		this.totalProventos = totalProventos;
	}

	public BigDecimal getHorasTrabalhadas() {
		return horasTrabalhadas;
	}

	public void setHorasTrabalhadas(BigDecimal horasTrabalhadas) {
		this.horasTrabalhadas = horasTrabalhadas;
	}
}
